from math import ceil

class TorrentTags:
    fileName = "NAME"
    trackerUrl = "TRACKER"
    size = "SIZE"
    chunkSize = "CHUNK"
    fileHash = "FILEHASH"
    pieceHash = "HASH"

#TagsOrder = ["NAME",
#             "TRACKER",
#             "SIZE",
#             "CHUNK",
#             "FILEHASH",
#             "HASH"]

def parseTorrent(torrentFile):
        
    class TorrentTags:
    	fileName = "NAME"
    	trackerUrl = "TRACKER"
    	size = "SIZE"
    	chunkSize = "CHUNK"
    	fileHash = "FILEHASH"
    	pieceHash = "HASH"

    torrent = open(torrentFile, "r")
    lines = torrent.readlines()
    
    tags = {}
    order = [TorrentTags.fileName,
             TorrentTags.trackerUrl,
             TorrentTags.size,
             TorrentTags.chunkSize,
             TorrentTags.fileHash,
             TorrentTags.pieceHash]

    tags[TorrentTags.pieceHash] = []
    for line in lines:
        if line.strip() == "":
            continue
        tokens = line.split(":",1)#Make only one split
        if len(tokens) == 1:
            print "Invalid File Format"
            print "Didn't find ':' at line: ", len(order)
            return 
        keyword = tokens[0]
        keyword = keyword.upper()
        if keyword != order[0]:
            #Lets ease the debugging.
            if keyword in order:
                print "Invalid Sequence found in torrent file."
                print "Expected: " + order[0] + "\tFound: " + keyword
            else:
                print "Unknown Tag found in torrent file"
                print "Found: " + keyword
            return 
        else:
            param = tokens[1]
            param = param.strip()
            #I've found tag that was expected according to sequence
            if len(order) != 1:# #More stupid design
                #It's piece Hash, it can get repeated any number of times
                order.pop(0)#Forward to the next tag.
                tags[keyword] = param
            else:
                tags[keyword] += [param]
                        
    if len(order) != 1:
        print "Incomplete Torrent File"
        return
    
    fileSize = int(tags[TorrentTags.size])
    chunkSizeKB = int(tags[TorrentTags.chunkSize])*1024
    expectedPieces = int(ceil(fileSize*1.0/chunkSizeKB))
    
    if expectedPieces != len(tags[TorrentTags.pieceHash]):
        print "Wrong number of file piece."
        print "Expected: " , expectedPieces
        print "Got: " , len(tags[TorrentTags.pieceHash])
        raise ValueError
    tags[TorrentTags.size] = fileSize #Put it as int
    tags[TorrentTags.chunkSize] = chunkSizeKB/1024#Put it as int
    return tags

if __name__ == '__main__':
    torrentName = "Lawrence.tor"
    torrDict = parseTorrent(torrentName)
    for entry in torrDict.keys():
        print entry.strip() + ":", torrDict[entry]